#include <QCoreApplication>

#include <iostream>
#include <cstdio>
#include <rpc/rpc.h>

#include "lww.h"

using namespace std;

void printColor(colors aColor)
{
    switch (aColor) {
    case RED:
        cout << "红色" << endl;
        break;
    case YELLOW:
        cout << "黄色" << endl;
        break;
    case BLUE:
        cout << "蓝色" << endl;
        break;
    case GREEN:
        cout << "绿色" << endl;
        break;
    default:
        cout << "错误色" << endl;
        break;
    }
}

void printBool(bool_t bPrint)
{
    switch (bPrint) {
    case TRUE:
        cout << "真" << endl;
        break;
    case FALSE:
        cout << "假" << endl;
        break;
    default:
        cout << "错误" << endl;
        break;
    }
}

int test_array_encode()
{
    cout << "begin" << endl;
    FILE *pFile = fopen("lww.txt", "wb");
    XDR xdr;
    xdrstdio_create(&xdr, pFile, XDR_ENCODE);

    colors aRED = RED;
    colors aYELLOW = YELLOW;
    colors aBLUE = BLUE;
    colors aGREEN = GREEN;
    lww_int aLwwInt;
    aLwwInt.m_nAge = 28;
    aLwwInt.m_bMale = TRUE;
    aLwwInt.m_sName = (char*)"1234";
    aLwwInt.m_ayColor[0] = GREEN;
    aLwwInt.m_ayColor[1] = BLUE;

    xdr_colors(&xdr, &aRED);
    xdr_colors(&xdr, &aYELLOW);
    xdr_colors(&xdr, &aBLUE);
    xdr_colors(&xdr, &aGREEN);
    xdr_lww_int(&xdr, &aLwwInt);

    xdr_destroy(&xdr);
    fclose(pFile);
    cout << "end" << endl;
    return 0;
}

int test_array_decode()
{
    cout << "begin" << endl;
    FILE *pFile = fopen("lww.txt", "rb");
    XDR xdr;
    xdrstdio_create(&xdr, pFile, XDR_DECODE);

    colors aColor;
    char sName[255] = {0};
    lww_int aLwwInt;
    aLwwInt.m_sName = sName;

    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_lww_int(&xdr, &aLwwInt);
    cout << aLwwInt.m_nAge << endl;
    printBool(aLwwInt.m_bMale);
    cout << aLwwInt.m_sName << endl;
    printColor(aLwwInt.m_ayColor[0]);
    printColor(aLwwInt.m_ayColor[1]);
    xdr_destroy(&xdr);
    fclose(pFile);
    cout << "end" << endl;
    return 0;
}

int use_x_file()
{
    cout << "begin x file" << endl;

    FILE *pFile = fopen("lww.txt", "rb");
    XDR xdr;
    xdrstdio_create(&xdr, pFile, XDR_DECODE);
    lww_int aLwwInt;
    xdr_lww_int(&xdr, &aLwwInt);
    xdr_destroy(&xdr);
    fclose(pFile);
    cout << "m_nAge: " << aLwwInt.m_nAge * 2 << endl;
    cout << "end x file" << endl;
    return 0;
}

// 使用文件编码 int
int encode_int_use_file()
{
    cout << "begin" << endl;

    FILE *pfile = fopen("lww.txt", "ab+");
    XDR xdr;
    xdrstdio_create(&xdr, pfile, XDR_ENCODE);
    int n = 300, m = 100;
    xdr_int(&xdr, &n);
    xdr_int(&xdr, &m);
    xdr_destroy(&xdr);
    fclose(pfile);

    cout << "xdr destroy" << endl;

    return 0;
}

// 从文件空间解码 int
int decode_int_use_file()
{
    cout << "begin" << endl;
    FILE *pfile = fopen("lww.txt", "rb");
    XDR xdr;
    xdrstdio_create(&xdr, pfile, XDR_DECODE);
    int n = 0, m = 0;
    cout << "before decode value is: " << n << m << endl;
    xdr_int(&xdr, &n);
    xdr_int(&xdr, &m);
    xdr_destroy(&xdr);
    fclose(pfile);
    cout << "after decode value is: " << n << m << endl;
    cout << "end" << endl;

    return 0;
}

void test_union_encode()
{
    cout << "begin" << endl;
    FILE *pFile = fopen("lww.txt", "wb");
    XDR xdr;
    xdrstdio_create(&xdr, pFile, XDR_ENCODE);

    colors aRed = RED;
    colors aYellow = YELLOW;
    colors aBlue = BLUE;
    colors aGreen = GREEN;
    lww_int aLwwInt;
    aLwwInt.m_nAge = 28;
    aLwwInt.m_bMale = TRUE;
    aLwwInt.m_sName = (char*)"1234";
    aLwwInt.m_ayColor[0] = GREEN;
    aLwwInt.m_ayColor[1] = BLUE;
    lww_union aLwwUnion;
    aLwwUnion.clr = RED;
    aLwwUnion.lww_union_u.m_nAge = 28 * 2;

    xdr_colors(&xdr, &aRed);
    xdr_colors(&xdr, &aYellow);
    xdr_colors(&xdr, &aBlue);
    xdr_colors(&xdr, &aGreen);
    xdr_lww_int(&xdr, &aLwwInt);
    xdr_lww_union(&xdr, &aLwwUnion);

    xdr_destroy(&xdr);
    fclose(pFile);
    cout << "end" << endl;
}

void test_union_decode()
{
    cout << "begin" << endl;
    FILE *pfile = fopen("lww.txt", "rb");
    XDR xdr;
    xdrstdio_create(&xdr, pfile, XDR_DECODE);
    colors aColor;
    char sName[255] = {0};
    lww_int aLwwInt;
    aLwwInt.m_sName = sName;
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_lww_int(&xdr, &aLwwInt);
    cout << aLwwInt.m_nAge << endl;
    printBool(aLwwInt.m_bMale);
    cout << aLwwInt.m_sName << endl;
    printColor(aLwwInt.m_ayColor[0]);
    printColor(aLwwInt.m_ayColor[1]);

    lww_union aLwwUnion;
    xdr_lww_union(&xdr, &aLwwUnion);
    if (RED == aLwwUnion.clr)
    {
        cout << aLwwUnion.lww_union_u.m_nAge << endl;
    }
    xdr_destroy(&xdr);
    fclose(pfile);
    cout << "endl" << endl;
}

lww_int aLwwInt;

void writeTLogFile(const char *str)
{
    FILE *pFileW = fopen("log.txt", "a+");
    if (NULL == pFileW) {
        return;
    }
    fprintf(pFileW, "\n%s", str);
    fclose(pFileW);
    return;
}

void writeBLogFile(const char *str, int nCount)
{
    FILE *pFileW = fopen("log.txt", "ab+");
    if (NULL == pFileW) {
        return;
    }
    fwrite(str, 1, nCount, pFileW);
    fclose(pFileW);
    return;
}

void test_varlen_encode()
{
    cout << "begin" << endl;
    FILE *pFile = fopen("lww.txt", "wb");
    XDR xdr;
    xdrstdio_create(&xdr, pFile, XDR_ENCODE);
    colors aRed = RED;
    colors aYellow = YELLOW;
    colors aBlue = BLUE;
    colors aGreen = GREEN;
    lww_int aLwwInt;
    aLwwInt.m_nAge = 28;
    aLwwInt.m_bMale = TRUE;
    aLwwInt.m_sName = (char*)"1234";
    aLwwInt.m_ayColor[0] = GREEN;
    aLwwInt.m_ayColor[1] = BLUE;
    lww_union aLwwUnion;
    aLwwUnion.clr = RED;
    aLwwUnion.lww_union_u.m_nAge = 28 * 2;

    xdr_colors(&xdr, &aRed);
    xdr_colors(&xdr, &aYellow);
    xdr_colors(&xdr, &aBlue);
    xdr_colors(&xdr, &aGreen);
    xdr_lww_int(&xdr, &aLwwInt);
    xdr_lww_union(&xdr, &aLwwUnion);
    xdr_destroy(&xdr);
    fclose(pFile);
    cout << "end" << endl;
}

void test_varlen_decode()
{
    cout << "begin" << endl;

    writeTLogFile("加载前：");
    writeBLogFile((char*)&aLwwInt, sizeof(aLwwInt));

    FILE *pFile = fopen("lww.txt", "rb");
    XDR xdr;
    xdrstdio_create(&xdr, pFile, XDR_DECODE);
    colors aColor;
//    char sName[255] = {0};
//    lww_int aLwwInt;
//    aLwwInt.m_sName = sName;
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_lww_int(&xdr, &aLwwInt);
    cout << aLwwInt.m_nAge << endl;
    printBool(aLwwInt.m_bMale);
    cout << aLwwInt.m_sName << endl;
    printColor(aLwwInt.m_ayColor[0]);
    printColor(aLwwInt.m_ayColor[1]);

    writeTLogFile("加载后:");
    writeBLogFile((char*)&aLwwInt, sizeof(aLwwInt));

    lww_union aLwwUnion;
    xdr_lww_union(&xdr, &aLwwUnion);
    if (RED == aLwwUnion.clr) {
        cout << aLwwUnion.lww_union_u.m_nAge << endl;
    }
    xdr_free((xdrproc_t)xdr_lww_int, (char*)&aLwwInt);

    writeTLogFile("释放后:");
    writeBLogFile((char*)&aLwwInt, sizeof(aLwwInt));

    xdr_destroy(&xdr);
    fclose(pFile);
    cout << "end" << endl;
}

void test_varArray_encode()
{
    cout << "begin" << endl;
    FILE *pFile = fopen("lww.txt", "wb");
    XDR xdr;
    xdrstdio_create(&xdr, pFile, XDR_ENCODE);
    colors aRed = RED;
    colors aYellow = YELLOW;
    colors aBlue = BLUE;
    colors aGreen = GREEN;
    lww_int aLwwInt;
    aLwwInt.m_nAge = 28;
    aLwwInt.m_bMale = TRUE;
    aLwwInt.m_sName = (char*)"1234";
    aLwwInt.m_ayColor[0] = GREEN;
    aLwwInt.m_ayColor[1] = BLUE;

    int naInt[2];
    naInt[0] = 1;
    naInt[1] = 2;
    aLwwInt.m_naNum.m_naNum_len = 2;
    aLwwInt.m_naNum.m_naNum_val = naInt;

    lww_union aLwwUnion;
    aLwwUnion.clr = RED;
    aLwwUnion.lww_union_u.m_nAge = 28 * 2;

    xdr_colors(&xdr, &aRed);
    xdr_colors(&xdr, &aYellow);
    xdr_colors(&xdr, &aBlue);
    xdr_colors(&xdr, &aGreen);
    xdr_lww_int(&xdr, &aLwwInt);
    xdr_lww_union(&xdr, &aLwwUnion);
    xdr_destroy(&xdr);
    fclose(pFile);
    cout << "end" << endl;
}

void writeB2TLogFile(const char *str, int nCount)
{
    char sBuffer[400] = {0};
    strcpy(sBuffer, "0X");
    char *pBuffer = sBuffer + 2;
    for (int i = 0; i < nCount; i++)
    {
        sprintf(pBuffer, "%02X", *str);
        str++;
        pBuffer += 2;
    }
    writeTLogFile(sBuffer);
    return;
}

void test_varArray_decode()
{
    cout << "begin" << endl;

    writeTLogFile("加载前：");
    writeB2TLogFile((char*)&aLwwInt, sizeof(aLwwInt));

    FILE *pFile = fopen("lww.txt", "rb");
    XDR xdr;
    xdrstdio_create(&xdr, pFile, XDR_DECODE);

    colors aColor;
//    char sName[255] = {0};
//    lww_int aLwwInt;
//    aLwwInt.m_sName = sName;
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_colors(&xdr, &aColor);
    printColor(aColor);
    xdr_lww_int(&xdr, &aLwwInt);
    cout << aLwwInt.m_nAge << endl;
    printBool(aLwwInt.m_bMale);
    cout << aLwwInt.m_sName << endl;
    printColor(aLwwInt.m_ayColor[0]);
    printColor(aLwwInt.m_ayColor[1]);
    cout << "长: " << aLwwInt.m_naNum.m_naNum_len << endl;
    cout << "元素0: " << aLwwInt.m_naNum.m_naNum_val[0] << endl;
    cout << "元素1: " << aLwwInt.m_naNum.m_naNum_val[0] << endl;

    writeTLogFile("加载后:");
    writeB2TLogFile((char*)&aLwwInt, sizeof(aLwwInt));

    lww_union aLwwUnion;
    xdr_lww_union(&xdr, &aLwwUnion);
    if (RED == aLwwUnion.clr) {
        cout << aLwwUnion.lww_union_u.m_nAge << endl;
    }
    xdr_free((xdrproc_t)xdr_lww_int, (char*)&aLwwInt);

    writeTLogFile("释放后:");
    writeB2TLogFile((char*)&aLwwInt, sizeof(aLwwInt));

    xdr_destroy(&xdr);
    fclose(pFile);
    cout << "end" << endl;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    test_varlen_encode();
    test_varlen_decode();

    return a.exec();
}
